local rtk = require("libluartk")

H3DataDir = rtk.getprop("app.binDir") .. "/lua/games/heroes3/data"

local function mkIndex(tbl)
	local ntbl = {}
	local k, v
	for k, v in pairs(tbl) do
		if k == "0" then
			k = 0
		end
		if v == "0" then
			v = 0
		end
		ntbl[k] = v
		ntbl[v] = k
	end
	return ntbl
end

function arrayAdd(arr, k, v)
	arr[k] = v
	arr[v] = k
end

function zeroBasedArray(...)
	local input = { ... }
	if type(input[1]) == "table" then
		input = input[1]
	end
	local arr = {}
	local k, v
	for k, v in ipairs(input) do
		arr[k - 1] = v
	end
	return mkIndex(arr)
end

local function load_lua_file(f)
	local fh = io.open(f, "rt")
	if not fh then
		return
	end
	local code = fh:read("*a")
	fh:close()
	local err
	code, err = load(code)
	assert(code, err)
	code, err = xpcall(code, debug.traceback)
	assert(code, err)
	return err
end

function readIds(dir, ...)
	local _, pattern
	local ids = {}
	dir = dir or H3DataDir
	for _, pattern in ipairs({ ... }) do
		--		printk(2,'Loading ids from %s/%s\n',dir,pattern)
		local files = rtk.findFiles(dir, pattern)
		local __, f
		for __, f in ipairs(files) do
			--			printk(2,'Loading ids from %s\n',f)
			local fh = io.open(f, "rt")
			local line = fh:read("*l")
			local lineno = 1
			local count = 0
			while line do
				line = line:match("[ \t]*(.*)")
				line = line:gsub("//.*$", "")
				if #line > 0 then
					local id, name = line:match("([0-9]+)[ \t]*[:=][ \t]*(.+)$")
					if id and name then
						id = tonumber(id)
						ids[name] = id
						ids[id] = name
						count = count + 1
					else
						rtk.printk(2, 'File "%s", line %d is invalid : "%s"\n', f, lineno, line)
					end
				end
				lineno = lineno + 1
				line = fh:read("*l")
			end
			fh:close()
			--			printk(2,'%d ids loaded from %s.\n',count,f)
		end
	end
	return ids
end

function patchIds(original, patch)
	rtk.table_each(patch, function(k, v)
		original[k] = v
		original[v] = k
	end)
end

H3MapInfoMagics = mkIndex({
	[0xe] = "RoE",
	[0x15] = "AB",
	[0x1c] = "SoD",
	[0x20] = "HotA",
	[0x33] = "WoG",
})

H3PlayerColors = mkIndex({
	Red = 0,
	Blue = 1,
	Tan = 2,
	Green = 3,
	Orange = 4,
	Purple = 5,
	Teal = 6,
	Pink = 7,
	None = 0xff,
})

H3VictoryConditionTypes = zeroBasedArray(
	"Artifact",
	"GatherTroop",
	"GatherResource",
	"BuildCity",
	"BuildGrail",
	"BeatHero",
	"CaptureCity",
	"BeatMonster",
	"TakeDwellings",
	"TakeMines",
	"TransportItem",
	"BeatAllMonsters",
	"Survive"
)
arrayAdd(H3VictoryConditionTypes, 255, "WinStandard")

H3FactionNames = zeroBasedArray({
	Castle = 0,
	Rampart = 1,
	Tower = 2,
	Inferno = 3,
	Necropolis = 4,
	Dungeon = 5,
	Stronghold = 6,
	Fortress = 7,
	Conflux = 8,
	Cove = 9,
	Random = 0xff,
})

-- 这个数组不对，屏蔽掉
H3Buildings = nil
	and zeroBasedArray(
		"内政厅",
		"议会",
		"国会",
		"堡垒",
		"大本营",
		"城堡",
		"酒馆",
		"铁匠铺",
		"市场",
		"物资仓库",
		"宝物商店",
		"1级魔法行会",
		"2级魔法行会",
		"3级魔法行会",
		"4级魔法行会",
		"5级魔法行会",
		"船坞",
		"神器",
		"1级兵",
		"升级1级兵",
		"1级兵群落",
		"2级兵",
		"升级2级兵",
		"2级兵群落",
		"3级兵",
		"升级3级兵",
		"3级兵群落",
		"4级兵",
		"升级4级兵",
		"4级兵群落",
		"5级兵",
		"升级5级兵",
		"5级兵群落",
		"6级兵",
		"升级6级兵",
		"7级兵",
		"升级7级兵"
	)

H3MineTypes = mkIndex({
	Sawmill = 0,
	AlchemistsLab = 1,
	OrePit = 2,
	SulfurDune = 3,
	CrystalCavern = 4,
	GemPond = 5,
	GoldMine = 6,
	AbandonedMine = 7,
})

H3ArtifactSlot = zeroBasedArray(
	"Head",
	"Shoulders",
	"Neck",
	"RightHand",
	"LeftHand",
	"Torso",
	"RightRing",
	"LeftRing",
	"Feet",
	"Misc1",
	"Misc2",
	"Misc3",
	"Misc4",
	"WarMachine1",
	"WarMachine2",
	"WarMachine3",
	"WarMachine4",
	"SpellBook",
	"Misc5",
	"Backpack"
)

H3TerrainTypes = zeroBasedArray(
	"Dirt",
	"Sand",
	"Grass",
	"Snow",
	"Swamp",
	"Rough",
	"Subterranean",
	"Lava",
	"Water",
	"Rock",
	"Highland"
)

H3ObjectTypes = zeroBasedArray("Object", "Town", "Monster", "Hero", "Artifact", "Treasure")

H3ObjectIds = mkIndex({
	-- 2025-8, wangdm001, WoG地图上的不明物体
	WogUnknown = 0,
	AltarOfSacrifice = 2,
	AnchorPoint = 3,
	Arena = 4,
	Artifact = 5,
	PandorasBox = 6,
	BlackMarket = 7,
	Boat = 8,
	BorderGuard = 9,
	KeymastersTent = 10,
	Buoy = 11,
	Campfire = 12,
	Cartographer = 13,
	SwanPond = 14,
	CoverOfDarkness = 15,
	CreatureBank = 16,
	CreatureGenerator1 = 17,
	CreatureGenerator2 = 18,
	CreatureGenerator3 = 19,
	CreatureGenerator4 = 20,
	CursedGround = 21,
	Corpse = 22,
	MarlettoTower = 23,
	DerelictShip = 24,
	DragonUtopia = 25,
	Event = 26,
	EyeOfTheMagi = 27,
	FaerieRing = 28,
	Flotsam = 29,
	FountainOfFortune = 30,
	FountainOfYouth = 31,
	GardenOfRevelation = 32,
	Garrison = 33,
	Hero = 34,
	HillFort = 35,
	Grail = 36,
	HutOfTheMagi = 37,
	IdolOfFortune = 38,
	LeanTo = 39,
	DecorativeObject = 40,
	LibraryOfEnlightenment = 41,
	Lighthouse = 42,
	MonolithOneWayEntrance = 43,
	MonolithOneWayExit = 44,
	MonolithTwoWay = 45,
	MagicPlains = 46,
	SchoolOfMagic = 47,
	MagicSpring = 48,
	MagicWell = 49,
	MarketOfTime = 50,
	MercenaryCamp = 51,
	Mermaids = 52,
	Mine = 53,
	Monster = 54,
	MysticalGarden = 55,
	Oasis = 56,
	Obelisk = 57,
	RedwoodObservatory = 58,
	OceanBottle = 59,
	PillarOfFire = 60,
	StarAxis = 61,
	Prison = 62,
	Object = 63, --subtype 0 - Pyramid, subtype > 0 - WoG object
	RallyFlag = 64,
	RandomArtifact = 65,
	RandomTreasureArtifact = 66,
	RandomMinorArtifact = 67,
	RandomMajorArtifact = 68,
	RandomRelicArtifact = 69,
	RandomHero = 70,
	RandomMonster = 71,
	RandomMonster1 = 72,
	RandomMonster2 = 73,
	RandomMonster3 = 74,
	RandomMonster4 = 75,
	RandomResource = 76,
	RandomTown = 77,
	RefugeeCamp = 78,
	Resource = 79,
	Sanctuary = 80,
	Scholar = 81,
	SeaChest = 82,
	SeersHut = 83,
	Crypt = 84,
	Shipwreck = 85,
	ShipwreckSurvivor = 86,
	Shipyard = 87,
	ShrineOfMagicIncantation = 88,
	ShrineOfMagicGesture = 89,
	ShrineOfMagicThought = 90,
	Sign = 91,
	Sirens = 92,
	SpellScroll = 93,
	Stables = 94,
	Tavern = 95,
	Temple = 96,
	DenOfThieves = 97,
	Town = 98,
	TradingPost = 99,
	LearningStone = 100,
	TreasureChest = 101,
	TreeOfKnowledge = 102,
	SubterraneanGate = 103,
	University = 104,
	Wagon = 105,
	WarMachineFactory = 106,
	SchoolOfWar = 107,
	WarriorsTomb = 108,
	WaterWheel = 109,
	WateringHole = 110,
	Whirlpool = 111,
	Windmill = 112,
	WitchHut = 113,
	Brush = 114,
	Bush = 115,
	Cactus = 116,
	Canyon = 117,
	Crater = 118,
	DeadVegetation = 119,
	Flowers = 120,
	FrozenLake = 121,
	Hedge = 122,
	Hill = 123,
	Hole = 124,
	Kelp = 125,
	Lake = 126,
	LavaFlow = 127,
	LavaLake = 128,
	Mushrooms = 129,
	Log = 130,
	Mandrake = 131,
	Moss = 132,
	Mound = 133,
	Mountain = 134,
	OakTrees = 135,
	Outcropping = 136,
	PineTrees = 137,
	Plant = 138,
	DecorativeObject2 = 139, -- HotA only (Waterfalls, frogs etc)
	DecorativeObject3 = 140, -- HotA only (Palms, Stones, Snow hills etc)
	MagicalTerrain = 141, -- HotA only
	ResourceWarehouse = 142, -- HotA only
	RiverDelta = 143,
	Building = 144, -- HotA only
	SeaObject = 145, -- HotA only
	Building2 = 146, -- HotA only
	Rock = 147,
	SandDune = 148,
	SandPit = 149,
	Shrub = 150,
	Skull = 151,
	Stalagmite = 152,
	Stump = 153,
	TarPit = 154,
	Trees = 155,
	Vine = 156,
	VolcanicVent = 157,
	Volcano = 158,
	WillowTrees = 159,
	YuccaTrees = 160,
	Reef = 161,
	RandomMonster5 = 162,
	RandomMonster6 = 163,
	RandomMonster7 = 164,
	Brush2 = 165,
	Bush2 = 166,
	Cactus2 = 167,
	Canyon2 = 168,
	Crater2 = 169,
	DeadVegetation2 = 170,
	Flowers2 = 171,
	FrozenLake2 = 172,
	Hedge2 = 173,
	Hill2 = 174,
	Hole2 = 175,
	Kelp2 = 176,
	Lake2 = 177,
	LavaFlow2 = 178,
	LavaLake2 = 179,
	Mushrooms2 = 180,
	Log2 = 181,
	Mandrake2 = 182,
	Moss2 = 183,
	Mound2 = 184,
	Mountain2 = 185,
	OakTrees2 = 186,
	Outcropping2 = 187,
	PineTrees2 = 188,
	Plant2 = 189,
	RiverDelta2 = 190,
	Rock2 = 191,
	SandDune2 = 192,
	SandPit2 = 193,
	Shrub2 = 194,
	Skull2 = 195,
	Stalagmite2 = 196,
	Stump2 = 197,
	TarPit2 = 198,
	Trees2 = 199,
	Vine2 = 200,
	VolcanicVent2 = 201,
	Volcano2 = 202,
	WillowTrees2 = 203,
	YuccaTrees2 = 204,
	Reef2 = 205,
	DesertHills = 206,
	DirtHills = 207,
	GrassHills = 208,
	RoughHills = 209,
	SubterraneanRocks = 210,
	SwampFoliage = 211,
	BorderGate = 212,
	FreelancersGuild = 213,
	HeroPlaceholder = 214,
	QuestGuard = 215,
	RandomDwelling = 216,
	RandomDwellingLevel = 217, -- SubId represents Level
	RandomDwellingFaction = 218, -- SubId represents Faction
	Garrison2 = 219,
	Mine2 = 220,
	TradingPost2 = 221,
	CloverField = 222,
	CursedGround2 = 223,
	EvilFog = 224,
	FavorableWinds = 225,
	FieryFields = 226,
	HolyGround = 227,
	LucidPools = 228,
	MagicClouds = 229,
	MagicPlains2 = 230,
	Rocklands = 231,
})

H3ResourceIds = zeroBasedArray("Wood", "Mercury", "Ore", "Sulfur", "Crystal", "Gems", "Gold", "Mithril")

H3PrimarySkills = zeroBasedArray("Attack", "Defense", "SpellPower", "Knowledge")

H3SecondarySkills = mkIndex({
	Pathfinding = 0,
	Archery = 1,
	Logistics = 2,
	Scouting = 3,
	Diplomacy = 4,
	Navigation = 5,
	Leadership = 6,
	Wisdom = 7,
	Mysticism = 8,
	Luck = 9,
	Ballistics = 10,
	EagleEye = 11,
	Necromancy = 12,
	Estates = 13,
	FireMagic = 14,
	AirMagic = 15,
	WaterMagic = 16,
	EarthMagic = 17,
	Scholar = 18,
	Tactics = 19,
	Artillery = 20,
	Learning = 21,
	Offense = 22,
	Armorer = 23,
	Intelligence = 24,
	Sorcery = 25,
	Resistance = 26,
	FirstAid = 27,
})

H3QuestTypes = zeroBasedArray(
	"None",
	"AchieveExperienceLevel",
	"AchievePrimarySkillLevel",
	"DefeatASpecificHero",
	"DefeatASpecificMonster",
	"ReturnWithArtifacts",
	"ReturnWithCreatures",
	"ReturnWithResources",
	"BeASpecificHero",
	"BelongToASpecificPlayer"
)

H3RewardTypes = zeroBasedArray(
	"None",
	"Experience",
	"SpellPoints",
	"Morale",
	"Luck",
	"Resource",
	"PrimarySkill",
	"SecondarySkill",
	"Artifact",
	"Spell",
	"Creatures"
)

H3ScholarBonusTypes = mkIndex({
	Random = 0xff,
	PrimarySkill = 0,
	SecondarySkill = 1,
	Spell = 2,
})

H3CreatureBankTypes = mkIndex({
	CyclopsStockpile = 0,
	DwarvenTreasury = 1,
	GriffinConservatory = 2,
	ImpCache = 3,
	MedusaStores = 4,
	NagaBank = 5,
	DragonFlyHive = 6,
	-- below ones are from WoG
	HuntingLodge = 11,
	SnowCoveredGrotto = 12,
	PalaceOfMartialSpirit = 13,
	CitadelOfPacification = 14,
	MonasteryOfMagicians = 15,
	LibraryOfLegends = 16,
	TransylvanianTavern = 17,
	HomeOfTheBat = 18,
	LostBottle = 19,
	Grotto = 20,
	-- below ones are from HotA
	BeholdersSanctuary = 21,
	TempleOfTheSea = 22,
	PirateCavern = 23,
	Mansion = 24,
	Spit = 25,
	RedTower = 26,
	BlackTower = 27,
	IvoryTower = 28,
	Churchyard = 29,
	ExperimentalShop = 30,
	WolfRaiderPicket = 31,
	Ruins = 32,
})

H3ObjectColors = mkIndex({
	LightBlue = 0,
	Green = 1,
	Red = 2,
	DarkBlue = 3,
	Brown = 4,
	Purple = 5,
	White = 6,
	Black = 7,
})

H3Heroes = readIds(nil, "heroes.*.txt")
H3CreatureGenerators_1 = readIds(nil, "creaturegenerators1.*.txt")
H3CreatureGenerators_4 = readIds(nil, "creaturegenerators4.*.txt")

H3Artifacts = readIds(nil, "artifacts.*.txt")
H3Creatures = readIds(nil, "monsters.*.txt")
H3Spells = readIds(nil, "spells.*.txt")

local lang = rtk.getprop("lang")
if lang then
	H3LangDir = H3DataDir .. "/" .. lang
	load_lua_file(H3LangDir .. "/ids.lua")
end
